﻿// See https://aka.ms/new-console-template for more information
using ExpressionAppTest;
using ExpressionAppTest.SqlBuilder;
using System.Linq.Expressions;
using System.Reflection;

namespace HelloWorld
{
    class Program
    {
        static List<Customer> customers;
        static void Main(string[] args)
        {
            {
                Expression<Func<Customer, bool>> SqlLambda = x => x.Name.StartsWith("王");
                string SqlStr = SqlHelperExtension.GetQueryableSql(customers, SqlLambda);
                Console.WriteLine(SqlStr);
            }
            {
                // 变量表达式
                ParameterExpression valueIndex = Expression.Variable(typeof(int), "index");
                // 变量表达式
                ParameterExpression valueCount = Expression.Variable(typeof(int), "count");
                // 跳出循环标志
                LabelTarget breakTarget = Expression.Label(typeof(int));
                // 块表达式
                BlockExpression blockExpression =
                    Expression.Block(
                        // 添加局部变量
                        new[] { valueCount },
                        // 为valueCount赋初值 valueCount=0
                        // Assign表示赋值运算符
                        Expression.Assign(valueCount, Expression.Constant(0, typeof(int))),
                        // loop循环
                        Expression.Loop(
                                // 如果为true 然后求和，否则跳出循环
                                Expression.IfThenElse(
                                // If(valueIndex<=100)
                                Expression.LessThanOrEqual(valueIndex, Expression.Constant(100, typeof(int))),
                                // valueCount=valueCount+valueIndex; valueIndex++;
                                Expression.AddAssign(valueCount, Expression.PostIncrementAssign(valueIndex)),
                                // 跳出循环
                                Expression.Break(breakTarget, valueCount)
                            ), breakTarget
                         )  // Loop ends
                     );
                var lam = Expression.Lambda<Func<int, int>>(blockExpression, valueIndex).Compile();
                var resiltInt = lam.Invoke(1);
                Console.WriteLine(resiltInt);
            }
        }

        /// <summary>
        /// 测试
        /// </summary>
        /// <param name="args"></param>
        static void Main2(string[] args)
        {
            {
                var count = 0;
                for (int index = 0; index <= 100; index++)
                {
                    count += index;
                }
                Console.WriteLine(count);
            }
            {
                ParameterExpression valueI = Expression.Variable(typeof(int), "index");
                ParameterExpression valueCount = Expression.Variable(typeof(int), "count");
                LabelTarget breakTarget = Expression.Label(typeof(int));
                BlockExpression blockExpression =
                    Expression.Block(
                        new[] { valueCount },
                        Expression.Assign(valueCount, Expression.Constant(0, typeof(int))),
                        Expression.Loop(
                                Expression.IfThenElse(
                                Expression.LessThanOrEqual(valueI, Expression.Constant(100, typeof(int))),
                                Expression.AddAssign(valueCount, Expression.PostIncrementAssign(valueI)),
                                Expression.Break(breakTarget, valueCount)
                             ), breakTarget
                       )  // loop end
                    );
                var lambda = Expression.Lambda<Func<int, int>>(blockExpression, valueI).Compile();
                var result = lambda.Invoke(1);
                Console.WriteLine(result);
            }

            {
                var count = 0;
                for (int index = 100; index <= 0; index--)
                {
                    count += index;
                }
                Console.WriteLine(count);
            }
            {
                ParameterExpression valueI = Expression.Variable(typeof(int), "index");
                ParameterExpression valueCount = Expression.Variable(typeof(int), "count");
                LabelTarget breakTarget = Expression.Label(typeof(int));
                BlockExpression blockExpression =
                    Expression.Block(
                        new[] { valueCount },
                        Expression.Assign(valueCount, Expression.Constant(1, typeof(int))),
                        Expression.Loop(
                                Expression.IfThenElse(
                                Expression.GreaterThanOrEqual(valueI, Expression.Constant(0, typeof(int))),
                                Expression.AddAssign(valueCount, Expression.PostDecrementAssign(valueI)),
                                Expression.Break(breakTarget, valueCount)
                            ), breakTarget
                         )  // Loop ends
                     );
                var lam = Expression.Lambda<Func<int, int>>(blockExpression, valueI).Compile();
                var lambda = Expression.Lambda<Func<int, int>>(blockExpression, valueI).Compile();
                var resiltInt = lam.Invoke(100);
                var resiltInt2 = lambda.Invoke(100);
                Console.WriteLine(resiltInt);
            }
        }
    }
}



